import axios, { AxiosResponse, AxiosError, InternalAxiosRequestConfig } from 'axios'
import { message } from 'antd'
import { HTTP_STATUS, MOCK_CONFIG, NO_TOKEN_URLS } from '@/constants'
import { tokenManager } from './tokenManager'

// 定义响应数据类型
interface ApiResponse<T = any> {
  data: T
  code: number
  msg: string
  success: boolean
}

// 获取环境变量
const API_BASE_URL = MOCK_CONFIG.ENABLED
  ? import.meta.env.VITE_APIFOX_BASE_URL
  : import.meta.env.VITE_API_BASE_URL
const API_TIMEOUT = import.meta.env.VITE_API_TIMEOUT
const API_PROXY_PREFIX = MOCK_CONFIG.ENABLED
  ? MOCK_CONFIG.APIFOX_URL
  : import.meta.env.VITE_API_PROXY_PREFIX

// 检查URL是否需要token的工具函数
const needsToken = (url: string): boolean => {
  return !NO_TOKEN_URLS.some(noTokenUrl => url.includes(noTokenUrl))
}

// 添加代理前缀的工具函数
const addProxyPrefix = (url: string): string => {
  if (!url || url.startsWith('http')) {
    return url
  }
  return `${API_PROXY_PREFIX}${url.startsWith('/') ? '' : '/'}${url}`
}

// 创建axios实例
const api = axios.create({
  baseURL: API_BASE_URL,
  timeout: parseInt(API_TIMEOUT) || 10000,
  headers: {
    'Content-Type': 'application/json',
  },
})

// 请求拦截器
api.interceptors.request.use(
  async (config: InternalAxiosRequestConfig) => {
    // 添加代理前缀
    if (config.url) {
      config.url = addProxyPrefix(config.url)
    }

    // 检查是否需要添加token
    if (config.url && needsToken(config.url)) {
      // 检查token是否过期，如果过期则尝试刷新
      if (tokenManager.isTokenExpired()) {
        const newToken = await tokenManager.refreshToken()
        if (newToken && config.headers) {
          config.headers.Authorization = `Bearer ${newToken}`
        }
      } else {
        // 添加访问令牌
        const token = tokenManager.getAccessToken()
        if (token && config.headers) {
          config.headers.Authorization = `Bearer ${token}`
        }
      }
    }

    // 添加请求时间戳（防止缓存）
    if (config.method === 'get') {
      config.params = {
        ...config.params,
        // _t: Date.now(),
      }
    }

    return config
  },
  (error: AxiosError) => {
    console.error('Request error:', error)
    return Promise.reject(error)
  }
)

// 响应拦截器
api.interceptors.response.use(
  (response: AxiosResponse<ApiResponse>) => {
    const { data, code, msg, success } = response.data

    console.log('Response response.data:', response.data)

    if (success || code === HTTP_STATUS.OK) {
      return data
    } else {
      message.error(msg || '请求失败')
      return Promise.reject(new Error(msg || '请求失败'))
    }
  },
  async (error: AxiosError<ApiResponse>) => {
    console.error('Response error:', error)

    if (error.response) {
      const { status, data } = error.response

      switch (status) {
        case HTTP_STATUS.UNAUTHORIZED:
          // Token过期，尝试刷新
          const newToken = await tokenManager.refreshToken()
          if (newToken && error.config) {
            // 重新发送原请求
            error.config.headers.Authorization = `Bearer ${newToken}`
            return api.request(error.config)
          }
          break

        case HTTP_STATUS.FORBIDDEN:
          message.error('拒绝访问，权限不足')
          break

        case HTTP_STATUS.NOT_FOUND:
          message.error('请求的资源不存在')
          break

        case 422:
          message.error(data?.msg || '请求参数错误')
          break

        case HTTP_STATUS.INTERNAL_SERVER_ERROR:
          message.error('服务器内部错误')
          break

        case 502:
          message.error('网关错误')
          break

        case 503:
          message.error('服务暂时不可用')
          break

        default:
          message.error(data?.msg || `请求失败 (${status})`)
      }
    } else if (error.request) {
      message.error('网络连接异常，请检查网络设置')
    } else {
      message.error('请求配置错误')
    }

    return Promise.reject(error)
  }
)

// API方法封装
export const apiClient = {
  // GET请求
  get: <T = any>(url: string, params?: any): Promise<T> => {
    return api.get(url, { params })
  },

  // POST请求
  post: <T = any>(
    url: string,
    data?: any,
    p0?: { headers: { 'Content-Type': string } }
  ): Promise<T> => {
    return api.post(url, data)
  },

  // PUT请求
  put: <T = any>(url: string, data?: any): Promise<T> => {
    return api.put(url, data)
  },

  // DELETE请求
  delete: <T = any>(url: string, params?: any): Promise<T> => {
    return api.delete(url, { params })
  },

  // PATCH请求
  patch: <T = any>(url: string, data?: any): Promise<T> => {
    return api.patch(url, data)
  },

  // 文件上传
  upload: <T = any>(
    url: string,
    file: File,
    onProgress?: (progress: number) => void
  ): Promise<T> => {
    const formData = new FormData()
    formData.append('file', file)

    return api.post(url, formData, {
      headers: {
        'Content-Type': 'multipart/form-data',
      },
      onUploadProgress: progressEvent => {
        if (onProgress && progressEvent.total) {
          const progress = Math.round((progressEvent.loaded * 100) / progressEvent.total)
          onProgress(progress)
        }
      },
    })
  },

  // 文件下载
  download: (url: string, filename?: string): Promise<void> => {
    return api
      .get(url, {
        responseType: 'blob',
      })
      .then(response => {
        const blob = new Blob([response.data], { type: response.headers['content-type'] })
        const downloadUrl = window.URL.createObjectURL(blob)
        const link = document.createElement('a')
        link.href = downloadUrl
        link.download = filename || 'download'
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
        window.URL.revokeObjectURL(downloadUrl)
      })
  },
}

// 导出默认实例
export default api
